home *** CD-ROM | disk | FTP | other *** search
/ Freelog 100 / FreelogNo100-NovembreDecembre2010.iso / Musique / solfege / solfege-win32-3.17.0.exe / {app} / bin / Lib / gopherlib.py < prev    next >
Text File  |  2006-02-18  |  6KB  |  210 lines

  1. """Gopher protocol client interface."""
  2.  
  3. __all__ = ["send_selector","send_query"]
  4.  
  5. import warnings
  6. warnings.warn("the gopherlib module is deprecated", DeprecationWarning,
  7.               stacklevel=2)
  8.  
  9. # Default selector, host and port
  10. DEF_SELECTOR = '1/'
  11. DEF_HOST     = 'gopher.micro.umn.edu'
  12. DEF_PORT     = 70
  13.  
  14. # Recognized file types
  15. A_TEXT       = '0'
  16. A_MENU       = '1'
  17. A_CSO        = '2'
  18. A_ERROR      = '3'
  19. A_MACBINHEX  = '4'
  20. A_PCBINHEX   = '5'
  21. A_UUENCODED  = '6'
  22. A_INDEX      = '7'
  23. A_TELNET     = '8'
  24. A_BINARY     = '9'
  25. A_DUPLICATE  = '+'
  26. A_SOUND      = 's'
  27. A_EVENT      = 'e'
  28. A_CALENDAR   = 'c'
  29. A_HTML       = 'h'
  30. A_TN3270     = 'T'
  31. A_MIME       = 'M'
  32. A_IMAGE      = 'I'
  33. A_WHOIS      = 'w'
  34. A_QUERY      = 'q'
  35. A_GIF        = 'g'
  36. A_HTML       = 'h'          # HTML file
  37. A_WWW        = 'w'          # WWW address
  38. A_PLUS_IMAGE = ':'
  39. A_PLUS_MOVIE = ';'
  40. A_PLUS_SOUND = '<'
  41.  
  42.  
  43. _names = dir()
  44. _type_to_name_map = {}
  45. def type_to_name(gtype):
  46.     """Map all file types to strings; unknown types become TYPE='x'."""
  47.     global _type_to_name_map
  48.     if _type_to_name_map=={}:
  49.         for name in _names:
  50.             if name[:2] == 'A_':
  51.                 _type_to_name_map[eval(name)] = name[2:]
  52.     if gtype in _type_to_name_map:
  53.         return _type_to_name_map[gtype]
  54.     return 'TYPE=%r' % (gtype,)
  55.  
  56. # Names for characters and strings
  57. CRLF = '\r\n'
  58. TAB = '\t'
  59.  
  60. def send_selector(selector, host, port = 0):
  61.     """Send a selector to a given host and port, return a file with the reply."""
  62.     import socket
  63.     if not port:
  64.         i = host.find(':')
  65.         if i >= 0:
  66.             host, port = host[:i], int(host[i+1:])
  67.     if not port:
  68.         port = DEF_PORT
  69.     elif type(port) == type(''):
  70.         port = int(port)
  71.     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  72.     s.connect((host, port))
  73.     s.sendall(selector + CRLF)
  74.     s.shutdown(1)
  75.     return s.makefile('rb')
  76.  
  77. def send_query(selector, query, host, port = 0):
  78.     """Send a selector and a query string."""
  79.     return send_selector(selector + '\t' + query, host, port)
  80.  
  81. def path_to_selector(path):
  82.     """Takes a path as returned by urlparse and returns the appropriate selector."""
  83.     if path=="/":
  84.         return "/"
  85.     else:
  86.         return path[2:] # Cuts initial slash and data type identifier
  87.  
  88. def path_to_datatype_name(path):
  89.     """Takes a path as returned by urlparse and maps it to a string.
  90.     See section 3.4 of RFC 1738 for details."""
  91.     if path=="/":
  92.         # No way to tell, although "INDEX" is likely
  93.         return "TYPE='unknown'"
  94.     else:
  95.         return type_to_name(path[1])
  96.  
  97. # The following functions interpret the data returned by the gopher
  98. # server according to the expected type, e.g. textfile or directory
  99.  
  100. def get_directory(f):
  101.     """Get a directory in the form of a list of entries."""
  102.     entries = []
  103.     while 1:
  104.         line = f.readline()
  105.         if not line:
  106.             print '(Unexpected EOF from server)'
  107.             break
  108.         if line[-2:] == CRLF:
  109.             line = line[:-2]
  110.         elif line[-1:] in CRLF:
  111.             line = line[:-1]
  112.         if line == '.':
  113.             break
  114.         if not line:
  115.             print '(Empty line from server)'
  116.             continue
  117.         gtype = line[0]
  118.         parts = line[1:].split(TAB)
  119.         if len(parts) < 4:
  120.             print '(Bad line from server: %r)' % (line,)
  121.             continue
  122.         if len(parts) > 4:
  123.             if parts[4:] != ['+']:
  124.                 print '(Extra info from server:',
  125.                 print parts[4:], ')'
  126.         else:
  127.             parts.append('')
  128.         parts.insert(0, gtype)
  129.         entries.append(parts)
  130.     return entries
  131.  
  132. def get_textfile(f):
  133.     """Get a text file as a list of lines, with trailing CRLF stripped."""
  134.     lines = []
  135.     get_alt_textfile(f, lines.append)
  136.     return lines
  137.  
  138. def get_alt_textfile(f, func):
  139.     """Get a text file and pass each line to a function, with trailing CRLF stripped."""
  140.     while 1:
  141.         line = f.readline()
  142.         if not line:
  143.             print '(Unexpected EOF from server)'
  144.             break
  145.         if line[-2:] == CRLF:
  146.             line = line[:-2]
  147.         elif line[-1:] in CRLF:
  148.             line = line[:-1]
  149.         if line == '.':
  150.             break
  151.         if line[:2] == '..':
  152.             line = line[1:]
  153.         func(line)
  154.  
  155. def get_binary(f):
  156.     """Get a binary file as one solid data block."""
  157.     data = f.read()
  158.     return data
  159.  
  160. def get_alt_binary(f, func, blocksize):
  161.     """Get a binary file and pass each block to a function."""
  162.     while 1:
  163.         data = f.read(blocksize)
  164.         if not data:
  165.             break
  166.         func(data)
  167.  
  168. def test():
  169.     """Trivial test program."""
  170.     import sys
  171.     import getopt
  172.     opts, args = getopt.getopt(sys.argv[1:], '')
  173.     selector = DEF_SELECTOR
  174.     type = selector[0]
  175.     host = DEF_HOST
  176.     if args:
  177.         host = args[0]
  178.         args = args[1:]
  179.     if args:
  180.         type = args[0]
  181.         args = args[1:]
  182.         if len(type) > 1:
  183.             type, selector = type[0], type
  184.         else:
  185.             selector = ''
  186.             if args:
  187.                 selector = args[0]
  188.                 args = args[1:]
  189.         query = ''
  190.         if args:
  191.             query = args[0]
  192.             args = args[1:]
  193.     if type == A_INDEX:
  194.         f = send_query(selector, query, host)
  195.     else:
  196.         f = send_selector(selector, host)
  197.     if type == A_TEXT:
  198.         lines = get_textfile(f)
  199.         for item in lines: print item
  200.     elif type in (A_MENU, A_INDEX):
  201.         entries = get_directory(f)
  202.         for item in entries: print item
  203.     else:
  204.         data = get_binary(f)
  205.         print 'binary data:', len(data), 'bytes:', repr(data[:100])[:40]
  206.  
  207. # Run the test when run as script
  208. if __name__ == '__main__':
  209.     test()
  210.